package com.xunyin.modules.device.rest;

import cn.hutool.core.util.StrUtil;
import com.xunyin.api.ApiResult;
import com.xunyin.common.bean.LocalUser;
import com.xunyin.constant.SystemConfigConstants;
import com.xunyin.enums.ErrorEnum;
import com.xunyin.modules.device.domain.TDevice;
import com.xunyin.modules.device.param.DeviceParam;
import com.xunyin.modules.device.service.TDeviceService;
import com.xunyin.modules.device.service.dto.TDeviceDto;
import com.xunyin.modules.log.AppLog;
import com.xunyin.modules.mtstore.service.StaffService;
import com.xunyin.modules.shareorder.domain.TShareOrder;
import com.xunyin.modules.shareorder.service.TShareOrderService;
import com.xunyin.nettyV.client.PubMsg;
import com.xunyin.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.*;

/**
 * <p>
 * 设备控制器
 * </p>
 *
 * @author admin
 * @since 2022-10-15
 */
@Slf4j
@RestController
@Api(value = "设备", tags = "共享空间:设备")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class DeviceController {

    //private Logger logger = LoggerFactory.getLogger(DeviceController.class);

    private final TDeviceService tDeviceService;

    private final TShareOrderService tShareOrderService;

    private final StaffService staffService;

    /**
     * 自研硬件给指定设备发送指令
     */
    @AppLog(value = "自研硬件给指定设备发送指令", type = 1)
    //@AuthCheck
    @PostMapping("/device/sendCommondProg")
    @ApiOperation(value = "自研硬件给指定设备发送指令", notes = "自研硬件给指定设备发送指令")
    public ApiResult<String> sendCommondProg(@Validated @RequestBody DeviceParam param) throws MqttException {

        // macAddr 硬件物理地址
        // commandType==1,发送电源开关
        // commandType==2,发送门锁开关
        // commandType==3,发送语音播报,voiceText
        // commandType==4,设备重启
        // switchFlag, 0 关  1  开
        // voiceText ,播报语音文字

/*        {
            "macAddr":"80646F0F380C",
            "commandType":3,
            "voiceText":"订单将在15分钟后到期！可通过小程序续单"
        }*/
        if(param.getType()==null){
            param.setType(0);
        }
        List relayList = new ArrayList<>();
        if(param.getType()==1){
            log.info("param.getSubPortStr():"+param.getSubPortStr());
            relayList.add(0);
            relayList.add(0);
            relayList.add(0);
            relayList.add(0);
            String[] subPortArr = param.getSubPortStr().split(",");
            for(int i =0;i<subPortArr.length;i++){
                log.info("subPortArr_"+i+":"+subPortArr[i]);
                relayList.set(i,subPortArr[i]);
            }
            log.info("relayList.toString()"+relayList.toString());
            for(int j=0;j<relayList.size();j++){
                log.info("relayList.get(j)_"+j+":"+relayList.get(j));
            }
/*            for(String str: subPortArr){
                relayList.add(Integer.valueOf(str));
            }*/
        }
        PubMsg.sendCommand(param.getMacAddr(), param.getCommandType(), param.getSwitchFlag(), param.getVoiceText(),param.getType(),relayList,"");

        return ApiResult.ok("操作成功");
    }

    /**
     * 门店管理员断电
     */
    @AppLog(value = "门店管理员断电", type = 1)
    //@AuthCheck
    @PostMapping("/device/adminClosePower")
    @ApiOperation(value = "门店管理员断电", notes = "门店管理员断电")
    public ApiResult<String> adminClosePower(@Validated @RequestBody DeviceParam param) throws Exception {
//        TDevice device = tDeviceService.getPowerDeviceByStoreRoomIdOrStoreId(param.getStoreId(), param.getStoreRoomId(), param.getDeviceType());
//        if (device != null) {
//            DeviceParam param1 = new DeviceParam();
//            param1.setType(1);
//            param1.setCommandType(1);
//            param1.setMacAddr(device.getMacAddr());
//            param1.setSubPortStr("0,0,0,0");
//            sendCommondProg(param1);
//            param1 = new DeviceParam();
//            param1.setCommandType(3);
//            param1.setMacAddr(device.getMacAddr());
//            param1.setVoiceText("电源已关，请收拾好贵重物品离开，欢迎下次光临");
//            sendCommondProg(param1);
//            return ApiResult.ok("success", "断电成功！");
//        }
        TDevice device = tDeviceService.getPowerDeviceByStoreRoomIdOrStoreId(param.getStoreId(), param.getStoreRoomId(), 2);
        if (device != null) {
            if (DeviceUtil1.adminLock(device.getDeviceNo())) {
                return ApiResult.ok("success", "断电成功！");
            } else {
                return ApiResult.fail("断电失败！");
            }
        }
        return ApiResult.fail("设备不存在");
    }

    /**
     * 门店管理员开门
     */
    @AppLog(value = "门店管理员开门", type = 1)
    //@AuthCheck
    @PostMapping("/device/adminOpenDoor")
    @ApiOperation(value = "门店管理员开门", notes = "门店管理员开门")
    public ApiResult<String> adminOpenDoor(@Validated @RequestBody DeviceParam param) throws Exception {
        // 根据设置的硬件方案,来控制不同品牌的下的硬件
        String hardwareProg = RedisUtil.get(SystemConfigConstants.XUNYIN_HARDWARE_PROG);
        String result = tDeviceService.adminOpenDoor(hardwareProg,param.getStoreId(),
                param.getStoreRoomId(),param.getDeviceType());
        ApiResult<String> apiResult = new ApiResult<String>();
        if (result.equals("success")) {
            apiResult.setMsg("开门成功！");
//            TDevice device = tDeviceService.getPowerDeviceByStoreRoomIdOrStoreId(param.getStoreId(), param.getStoreRoomId(), 4);
//            if (device != null) {
//                DeviceParam param1 = new DeviceParam();
//                param1.setType(1);
//                param1.setCommandType(1);
//                param1.setMacAddr(device.getMacAddr());
//                param1.setSubPortStr("1,0,0,0");
//                sendCommondProg(param1);
//                param1 = new DeviceParam();
//                param1.setCommandType(3);
//                param1.setMacAddr(device.getMacAddr());
//                param1.setVoiceText("欢迎光临");
//                sendCommondProg(param1);
//            }
            TDevice device = tDeviceService.getPowerDeviceByStoreRoomIdOrStoreId(param.getStoreId(), param.getStoreRoomId(), 2);
            if (device != null) {
                if (StringUtils.isNotEmpty(param.getEndTime())) {
                    if (DeviceUtil1.userUnlock(device.getDeviceNo(), new Date(), DateUtil.parseStrint2Date(param.getEndTime(), "yyyy-MM-dd HH:mm"))) {
                        return ApiResult.ok(result, "开门成功！");
                    }
                } else {
                    if (DeviceUtil1.adminUnlock(device.getDeviceNo())) {
                        return ApiResult.ok(result, "开门成功！");
                    }
                }
            }
            return ApiResult.fail("开门失败！");
        } else if (result.equals(ErrorEnum.E_100024.getErrorCode())) {
            //return ApiResult.fail(ErrorEnum.E_100024.getErrorMsg());
            apiResult.setMsg(ErrorEnum.E_100024.getErrorMsg());
            return ApiResult.ok(result, ErrorEnum.E_100024.getErrorMsg());
        } else if (result.equals(ErrorEnum.E_100025.getErrorCode())) {
            //return ApiResult.fail(ErrorEnum.E_100025.getErrorMsg());
            apiResult.setMsg(ErrorEnum.E_100025.getErrorMsg());
            return ApiResult.ok(result, ErrorEnum.E_100025.getErrorMsg());
        }
        return null;
    }

    /**
     * 开门
     */
    @AppLog(value = "开门", type = 1)
    //@AuthCheck
    @PostMapping("/device/openDoor")
    @ApiOperation(value = "开门", notes = "开门")
    public ApiResult<String> openDoor(@Validated @RequestBody DeviceParam param) throws Exception {

        log.info("openDoor -> param_orderId = {},param_switchid = {}", param.getOrderId(), param.getSwitchid());
        TDeviceDto tDeviceDto = new TDeviceDto();
        tDeviceDto.setOrderId(param.getOrderId());
        tDeviceDto.setSwitchid(param.getSwitchid());
        String result = "";
        // 根据设置的硬件方案,来控制不同品牌的下的硬件
        String hardwareProg = RedisUtil.get(SystemConfigConstants.XUNYIN_HARDWARE_PROG);
        // 默认选择第三方硬件方案（涂鸦、通通锁）
        if (StrUtil.isBlank(hardwareProg)) {

            result = tDeviceService.openDoor(tDeviceDto);

        } else {

            // 自研硬件方案
            if (hardwareProg.equals("1")) {
                String tel = LocalUser.getUNameByToken();
                tDeviceDto.setAdmin(tel == null ? false : staffService.queryNormalStaffByMobile(tel) != null);
                result = tDeviceService.openDoorProg1(tDeviceDto);

            // 第三方硬件方案（涂鸦、通通锁）
            } else {
                String tel = LocalUser.getUNameByToken();
                tDeviceDto.setAdmin(tel == null ? false : staffService.queryNormalStaffByMobile(tel) != null);
                result = tDeviceService.openDoor(tDeviceDto);

            }
        }

        ApiResult<String> apiResult = new ApiResult<String>();
        if (result.equals("success")) {
            apiResult.setMsg("开门成功！");
            TShareOrder tShareOrder = tShareOrderService.selectById(tDeviceDto.getOrderId());
//            TDevice device = tDeviceService.getPowerDeviceByStoreRoomIdOrStoreId(tShareOrder.getStoreId(), tShareOrder.getStoreRoomId(), 4);
//            if (device != null) {
//                DeviceParam param1 = new DeviceParam();
//                param1.setType(1);
//                param1.setCommandType(1);
//                param1.setMacAddr(device.getMacAddr());
//                param1.setSubPortStr("1,0,0,0");
//                sendCommondProg(param1);
//                param1 = new DeviceParam();
//                param1.setCommandType(3);
//                param1.setMacAddr(device.getMacAddr());
//                param1.setVoiceText("欢迎光临");
//                sendCommondProg(param1);
//            }
//            return ApiResult.ok(result, "开门成功！");
            TDevice device = tDeviceService.getPowerDeviceByStoreRoomIdOrStoreId(tShareOrder.getStoreId(), tShareOrder.getStoreRoomId(), 2);
            if (device != null) {
                if (tDeviceDto.isAdmin()) {
                    if (DeviceUtil1.adminUnlock(device.getDeviceNo())) {
                        return ApiResult.ok(result, "开门成功！");
                    }
                } else {
                    if (DeviceUtil1.userUnlock(device.getDeviceNo(), tShareOrder.getTeaServerStartTime(), tShareOrder.getTeaServerEndTime())) {
                        return ApiResult.ok(result, "开门成功！");
                    }
                }
            }
            return ApiResult.fail("开门失败，请联系管理员！");
        } else if (result.equals(ErrorEnum.E_100024.getErrorCode())) {
            //return ApiResult.fail(ErrorEnum.E_100024.getErrorMsg());
            apiResult.setMsg(ErrorEnum.E_100024.getErrorMsg());
            return ApiResult.ok(result, ErrorEnum.E_100024.getErrorMsg());
        } else if (result.equals(ErrorEnum.E_100025.getErrorCode())) {
            //return ApiResult.fail(ErrorEnum.E_100025.getErrorMsg());
            apiResult.setMsg(ErrorEnum.E_100025.getErrorMsg());
            return ApiResult.ok(result, ErrorEnum.E_100025.getErrorMsg());
        }
        //return ApiResult.ok();
        return null;
    }

    /**
     * 远程开门
     *
     * @param param
     * @return
     */
    @AppLog(value = "开门", type = 1)
    //@AuthCheck
    @PostMapping("/manage/remote/openDoor")
    @ApiOperation(value = "开门", notes = "开门")
    public ApiResult<String> remoteOpenDoor(@Validated @RequestBody DeviceParam param) throws Exception {
        Integer doorDeviceId = param.getDoorDeviceId();
        String result = "";
        // 根据设置的硬件方案,来控制不同品牌的下的硬件
        String hardwareProg = RedisUtil.get(SystemConfigConstants.XUNYIN_HARDWARE_PROG);
        // 默认选择涂鸦硬件方案
        if (StrUtil.isBlank(hardwareProg)) {
            result = tDeviceService.remoteOpenDoor(doorDeviceId);
        } else {

            // 自研硬件方案
            if (hardwareProg.equals("1")) {

                result = tDeviceService.remoteOpenDoorProg1(doorDeviceId);

            // 第三方硬件方案（涂鸦、通通锁）
            } else {

                result = tDeviceService.remoteOpenDoor(doorDeviceId);

            }
        }
        if (result.equals("success")) {
            return ApiResult.ok(result);
        } else if (result.equals(ErrorEnum.E_100021.getErrorCode())) {
            return ApiResult.fail(ErrorEnum.E_100021.getErrorMsg());
        } else if (result.equals(ErrorEnum.E_90004.getErrorCode())) {
            return ApiResult.fail(ErrorEnum.E_90004.getErrorMsg());
        } else if (result.equals(ErrorEnum.E_100025.getErrorCode())) {
            return ApiResult.fail(ErrorEnum.E_100025.getErrorMsg());
        } else if (result.equals(ErrorEnum.E_100020.getErrorCode())) {
            return ApiResult.fail(ErrorEnum.E_100020.getErrorMsg());
        }
        return ApiResult.ok("开门成功");
        //return null;
    }

    /**
     * 根据门店id -所有包间的门禁复位
     */
    @AppLog(value = "根据门店id -所有包间的门禁复位", type = 1)
    //@AuthCheck
    @PostMapping("/manage/doorResetByTeaId")
    @ApiOperation(value = "根据门店id -所有包间的门禁复位", notes = "根据门店id -所有包间的门禁复位")
    public ApiResult<String> doorResetByTeaId(@Validated @RequestBody DeviceParam param) throws Exception {

        Boolean allSuccess = tDeviceService.doorResetByStoreId(param.getStoreId());
        // 根据设置的硬件方案,来控制不同品牌的下的硬件
        String hardwareProg = RedisUtil.get(SystemConfigConstants.XUNYIN_HARDWARE_PROG);
        // 默认选择涂鸦硬件方案
        if (StrUtil.isBlank(hardwareProg)) {
            allSuccess = tDeviceService.doorResetByStoreId(param.getStoreId());
        } else {
            // 自研硬件方案
            if (hardwareProg.equals("1")) {
                allSuccess = tDeviceService.doorResetByStoreIdProg1(param.getStoreId());

            // 第三方硬件方案（涂鸦、通通锁）
            } else {

                allSuccess = tDeviceService.doorResetByStoreId(param.getStoreId());

            }
        }
        if (allSuccess) {
            return ApiResult.ok("全部重置成功！");
        } else {
            return ApiResult.fail("部分重置失败！");
        }
    }

    /**
     * 根据门店id -所有包间的门禁设备
     */
    @AppLog(value = "根据门店id -所有包间的门禁设备", type = 1)
    //@AuthCheck
    @PostMapping("/getDoorListByTeaId")
    @ApiOperation(value = "根据门店id -所有包间的门禁设备", notes = "根据门店id -所有包间的门禁设备")
    public ApiResult<Map<String, Object>> getDoorListByTeaHouseId(@Validated @RequestBody DeviceParam param) throws IOException {
        //List<TDevice> resList = tDeviceService.getDoorListByTeaHouseId(param.getTeaHouseId());
        List<TDevice> resList = new ArrayList<TDevice>();
        // 根据设置的硬件方案,来控制不同品牌的下的硬件
        String hardwareProg = RedisUtil.get(SystemConfigConstants.XUNYIN_HARDWARE_PROG);
        // 默认选择涂鸦硬件方案
        if (StrUtil.isBlank(hardwareProg)) {

            resList = tDeviceService.getDeviceListByStoreRoomIdOrStoreId
                    (param.getStoreId(), null, 1);
        } else {

            // 自研硬件方案
            if (hardwareProg.equals("1")) {

                resList = tDeviceService.getDeviceListByStoreRoomIdOrStoreId
                        (param.getStoreId(), null, 4);

            // 第三方硬件方案（涂鸦、通通锁）
            } else {

                resList = tDeviceService.getDeviceListByStoreRoomIdOrStoreId
                        (param.getStoreId(), null, 1);
            }
        }

        Map<String, Object> map = new LinkedHashMap<>();
        map.put("doorDevices", resList);
        return ApiResult.ok(map);
    }
}
